package service

import (
	"context"
	"gitee.com/hxchjm/go-admin/internal/dao"
	"gitee.com/hxchjm/go-admin/internal/models"
	"gitee.com/hxchjm/go-admin/pkg/cas"
	"gitee.com/hxchjm/go-admin/pkg/ecode"
	"gitee.com/hxchjm/go-admin/pkg/jwtauth"
	"github.com/hxchjm/log"
	"github.com/jinzhu/copier"
	"golang.org/x/crypto/bcrypt"
)

type User struct {
}

func (e User) GetPage(ctx context.Context, req *models.ReqUserGetPage) (rsp *models.RspUserGetPage, err error) {
	//var su dao.SysUser
	//_ = copier.CopyWithOption(&su, req, copier.Option{IgnoreEmpty: true})
	res, cnt, err := dao.SysUser{}.GetList(ctx, req)
	if err != nil {
		return
	}
	rsp = &models.RspUserGetPage{
		Total: int(cnt),
		Page:  req.Page,
		Size:  req.Size,
	}
	for _, v := range res {
		rsp.List = append(rsp.List, v.SysUser)
	}
	return
}
func (e User) Get(ctx context.Context, req *models.ReqUserGet) (rsp interface{}, err error) {
	rsp, err = dao.SysUser{SysUser: models.SysUser{UserId: req.Id}}.Get(ctx)
	if err != nil {
		return nil, err
	}
	return
}
func (e User) Insert(ctx context.Context, req *models.ReqUserInsert) (rsp any, err error) {
	if err = (dao.SysUser{SysUser: *req}).Insert(ctx); err != nil {
		return
	}
	if err = cas.GetIns().LoadPolicy(); err != nil {
		log.Errorf(ctx, "load policy err (%+v),req(%+v)", err, req)
		return
	}
	return
}
func (e User) Update(ctx context.Context, req *models.ReqUserUpdate) (rsp any, err error) {
	if err = (dao.SysUser{SysUser: *req}).Update(ctx); err != nil {
		return
	}
	if err = cas.GetIns().LoadPolicy(); err != nil {
		log.Errorf(ctx, "load policy err (%+v),req(%+v)", err, req)
		return
	}
	return
}
func (e User) Delete(ctx context.Context, req *models.ReqUserDelete) (rsp any, err error) {
	if err = (dao.SysUser{}).Delete(ctx, req.Ids); err != nil {
		return
	}
	return
}

// UpdateStatus 修改用户状态
// @Summary 修改用户状态
// @Description 获取JSON
// @Tags 用户
// @Accept  application/json
// @Product application/json
// @Param data body dto.UpdateSysUserStatusReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/user/status [put]
// @Security Bearer
func (e User) UpdateStatus(ctx context.Context, req *models.ReqUserUpdate) (any, error) {

	req.UpdateBy = jwtauth.GetClaims(ctx).UID

	//数据权限检查
	//p := actions.GetPermissionFromContext(c)
	su := dao.SysUser{}
	_ = copier.Copy(&su, req)
	if err := (dao.SysUser{}).UpdateStatus(ctx); err != nil {
		log.Errorf(ctx, "update status err (%+v)", err)
		return nil, err
	}
	return req.UserId, nil
}

// ResetPwd 重置用户密码
// @Summary 重置用户密码
// @Description 获取JSON
// @Tags 用户
// @Accept  application/json
// @Product application/json
// @Param data body dto.ResetSysUserPwdReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/user/pwd/reset [put]
// @Security Bearer
func (e User) ResetPwd(ctx context.Context, req *models.ReqResetSysUserPwd) (any, error) {

	req.UpdateBy = jwtauth.GetClaims(ctx).UID
	//数据权限检查

	if err := (dao.SysUser{SysUser: models.SysUser{UserId: req.UserId, Password: req.Password}}).ResetPwd(ctx); err != nil {
		log.Errorf(ctx, "reset password err (%+v)", err)
		return nil, err
	}
	return req.UserId, nil
}

// UpdatePwd
// @Summary 修改密码
// @Description 获取JSON
// @Tags 用户
// @Accept  application/json
// @Product application/json
// @Param data body dto.PassWord true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/user/pwd/set [put]
// @Security Bearer
func (e User) UpdatePwd(ctx context.Context, req *models.ReqUpdatePwd) error {
	sd := dao.SysUser{}

	// 数据权限检查
	//p := actions.GetPermissionFromContext(c)
	//var hash []byte
	hash, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
	if err != nil {
		req.NewPassword = string(hash)
	}

	if err = sd.UpdatePwd(ctx, req.OldPassword, req.NewPassword); err != nil {
		log.Errorf(ctx, "Update pwd err (%+v)", err)
		return ecode.New(-1, "密码修改失败")
	}
	return nil
}

// GetProfile
// @Summary 获取个人中心用户
// @Description 获取JSON
// @Tags 个人中心
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/user/profile [get]
// @Security Bearer
func (e User) GetProfile(ctx context.Context, req *models.SysUserById) (any, error) {

	req.Id = int(jwtauth.GetClaims(ctx).UID)
	sysUser := models.SysUser{}
	roles := make([]models.SysRole, 0)
	posts := make([]models.SysPost, 0)
	if err := (dao.SysUser{SysUser: models.SysUser{UserId: req.Id}}).GetProfile(ctx, &sysUser, &roles, &posts); err != nil {
		log.Errorf(ctx, "get user profile error, %s", err.Error())
		return nil, ecode.New(-1, "获取用户信息失败")
	}
	if sysUser.RoleId != 0 {
		sysUser.RoleIds = append(sysUser.RoleIds, sysUser.RoleId)
	}
	return map[string]interface{}{
		"user":  sysUser,
		"roles": roles,
		"posts": posts,
	}, nil
}

// GetInfo
// @Summary 获取个人信息
// @Description 获取JSON
// @Tags 个人中心
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/v1/getinfo [get]
// @Security Bearer
func (e User) GetInfo(ctx context.Context) (any, error) {
	//req := models.SysUserById{}
	//p := actions.GetPermissionFromContext(c)
	var roles = make([]string, 1)
	roles[0] = jwtauth.GetClaims(ctx).RoleKey
	var permissions = make([]string, 1)
	permissions[0] = "*:*:*"
	var buttons = make([]string, 1)
	buttons[0] = "*:*:*"

	var mp = make(map[string]interface{})
	mp["roles"] = roles
	if roles[0] == "admin" {
		mp["permissions"] = permissions
		mp["buttons"] = buttons
	} else {
		list, _ := dao.SysRole{SysRole: models.SysRole{RoleKey: roles[0]}}.GetByKey(ctx)
		mp["permissions"] = list
		mp["buttons"] = list
	}
	sysUser := models.SysUser{}
	id := jwtauth.GetClaims(ctx).UID
	user, err := (dao.SysUser{SysUser: models.SysUser{UserId: id}}).Get(ctx)
	if err != nil {
		return nil, ecode.ERRLogin
	}
	_ = copier.Copy(&sysUser, user)
	mp["introduction"] = " am a super administrator"
	mp["avatar"] = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
	if sysUser.Avatar != "" {
		mp["avatar"] = sysUser.Avatar
	}
	mp["userName"] = sysUser.NickName
	mp["userId"] = sysUser.UserId
	mp["deptId"] = sysUser.DeptId
	mp["name"] = sysUser.NickName
	mp["code"] = 200
	return mp, nil
}
